/**
*   \file   Plane.h
*   \author Dave Reid
*   \brief  Header file for the Plane class.
*/
#ifndef __EAGL_PLANE_H_
#define __EAGL_PLANE_H_

#include "../types.h"
#include "../Shapes/Point3.h"

namespace eagl
{

/**
*   \brief  Class representing a plane.
*
*   A plane is defined by a normal and the distance to the origin.
*/
class Plane
{
public:

    /**
    *   \brief  Default constructor.
    */
    Plane() : m_normal(0.0f, 0.0f, 1.0f), m_distance(0.0f)
    {
    }

    /**
    *   \brief              Constructor.
    *   \param  normal [in] The normal of the plane.
    *   \param  dist   [in] The distance of the plane to the origin.
    */
    Plane(const vec3 &normal, float dist) : m_normal(normal), m_distance(dist)
    {
    }

    /**
    *   \brief          Constructor for building the plane from three points (a triangle).
    *   \param  p0 [in] The first point.
    *   \param  p1 [in] The second point.
    *   \param  p2 [in] The third point.
    *
    *   \remarks
    *       The points must be ordered anti-clockwise.
    */
    Plane(const Point3 &p0, const Point3 &p1, const Point3 &p2)
    {
        this->m_normal = glm::normalize(glm::cross(p1.getPosition() - p0.getPosition(), p2.getPosition() - p0.getPosition()));
        this->m_distance = glm::dot(this->m_normal, p0.getPosition());
    }


    /**
    *   \brief  Retrieves the normal of the plane.
    *   \return The normal of the plane.
    */
    const vec3 & getNormal() const
    {
        return this->m_normal;
    }

    /**
    *   \brief              Sets the normal of the plane.
    *   \param  normal [in] The new normal of the plane.
    */
    void setNormal(const vec3 &normal)
    {
        this->m_normal = normal;
    }

    /**
    *   \brief  Retrieves the distance from the origin to the plane.
    *   \return The distance to the plane from the origin.
    */
    float getDistance() const
    {
        return this->m_distance;
    }

    /**
    *   \brief            Sets the distance of the plane from the origin.
    *   \param  dist [in] The new distance from the origin.
    */
    void setDistance(float dist)
    {
        this->m_distance = dist;
    }



private:

    /// The normal of the plane.
    vec3 m_normal;

    /// The distance from the origin.
    float m_distance;

};

}

#endif  // __EAGL_PLANE_H_